/**
  * 20220304:[require] to [import]...jordia
 */
import {EventDispatcher} from 'three';
import Utils from '../general/utils';
import EP from './expression';


/**
 * 未规范化，存粹纪念
 *任意参数方程的N阶导数,偏导,不支持绝对值等分段函数
 *the way to add a function:
 *
 *               _monomial
 *                  |
 *              checkMonomial
 *         _________|_________
 *         |true             |false
 *        dev               dev
 *         |                 |
 *    computeMonomial       decomposeByOperator
 *         |                 |
 *    _monoDev              devOP
 *
 *添加checkUnsupportFunction
 *化简还有待进一步完善
 */


/**
 * 运算符求导
 */
class DevOperater{
    constructor(sign,index){
        this.sign=sign;
        this.index=index;
    }
}

/**
 * 支持的单项式类型及检测
 * @private
 */
let _monomial={
    type:{
        para:'parameter',
        oneParaFuc:'functionWithOneParameter',
        twoParaFuc:'functionWithTwoParameter',
        num:'number',
        exp:'exp',
        pow:'power',
        log:'log',
        sin:'sin',
        cos:'cos',
        tan:'tan,',
        cot:'cot',
        sec:'sec',
        csc:'csc',
        arcsin:'arcsin',
        arccos:'arccos',
        arctan:'arctan',
        arccot:'arccot'
    },
    num:(Array,dt,PE)=> {
        for(let i=0;i<Array.length;i++){
            if(Array[i]===dt)return false;
        }
        return true;
    },
    para:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        let tNum=0;
        let pCount=0;
        for(let i=0;i<array.length;i++){
            if(typeof (array[i])!=='string')return false;
            if(array[i]===PE.operatorReplaceTable.psl.oriStr)pCount++;
            if(array[i]===PE.operatorReplaceTable.psr.oriStr)pCount--;
            if(array[i]===dt){
                if(pCount>0){
                    return false;
                }else if(array[i-1]!==undefined&&array[i-1]===PE.operatorReplaceTable.exp.oriStr){
                    return false;
                }else{
                    tNum++;
                }
            }
        }
        return tNum===1;
    },
    oneParaFuc:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        let tNum=0;
        let pCount=0;
        for(let i=0;i<array.length;i++){
            if(typeof (array[i])!=='string')return false;
            if(array[i]===PE.operatorReplaceTable.psl.oriStr)pCount++;
            if(array[i]===PE.operatorReplaceTable.psr.oriStr)pCount--;
            if(PE.isFunctionReplaceElement(array[i])){
                if(array[i-1]===PE.operatorReplaceTable.exp.oriStr)return false;
            }
            if(array[i]===dt){
                if(pCount!==1){
                    return false;
                }else{
                    tNum++;
                    if(array[i-1]===undefined||array[i-1]!==PE.operatorReplaceTable.psl.oriStr)return false;
                    if(array[i+1]===undefined||array[i+1]!==PE.operatorReplaceTable.psr.oriStr)return false;
                }
            }
        }
        return tNum===1;
    },
    twoParaFuc:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        let tNum=0;
        let pCount=0;
        for(let i=0;i<array.length;i++){
            if(typeof (array[i])!=='string')return false;
            if(array[i]===PE.operatorReplaceTable.psl.oriStr)pCount++;
            if(array[i]===PE.operatorReplaceTable.psr.oriStr)pCount--;
            if(PE.isFunctionReplaceElement(array[i])){
                if(array[i-1]===PE.operatorReplaceTable.exp.oriStr)return false;
            }
            if(array[i]===dt){
                if(pCount!==1){
                    return false;
                }else{
                    tNum++;
                    if(array[i-1]===undefined|| (array[i-1]!==PE.operatorReplaceTable.psl.oriStr
                        &&array[i-1]!==PE.operatorReplaceTable.cma.oriStr))return false;
                    if(array[i+1]===undefined||(array[i+1]!==PE.operatorReplaceTable.psr.oriStr
                        &&array[i+1]!==PE.operatorReplaceTable.cma.oriStr))return false;
                }
            }
        }
        return tNum===1;
    },
    sin:(Array,dt,PE)=> {
        return Derivative.checkFunctionMonomialType(Array,PE.functionReplaceTable.sin.oriStr,PE);
    },
    pow:(Array,dt,PE)=> {
        return Derivative.checkFunctionMonomialType(Array,PE.functionReplaceTable.pow.oriStr,PE);
    },
    cos:(Array,dt,PE)=> {
        return Derivative.checkFunctionMonomialType(Array,PE.functionReplaceTable.cos.oriStr,PE);
    },
    tan:(Array,dt,PE)=> {
        return Derivative.checkFunctionMonomialType(Array,PE.functionReplaceTable.tan.oriStr,PE);
    },
    cot:(Array,dt,PE)=> {
        return Derivative.checkFunctionMonomialType(Array,PE.functionReplaceTable.cot.oriStr,PE);
    },
    sec:(Array,dt,PE)=> {
        return Derivative.checkFunctionMonomialType(Array,PE.functionReplaceTable.sec.oriStr,PE);
    },
    csc:(Array,dt,PE)=> {
        return Derivative.checkFunctionMonomialType(Array,PE.functionReplaceTable.csc.oriStr,PE);
    },
    arcsin:(Array,dt,PE)=> {
        return Derivative.checkFunctionMonomialType(Array,PE.functionReplaceTable.asin.oriStr,PE);
    },
    arccos:(Array,dt,PE)=> {
        return Derivative.checkFunctionMonomialType(Array,PE.functionReplaceTable.acos.oriStr,PE);
    },
    arctan:(Array,dt,PE) =>{
        return Derivative.checkFunctionMonomialType(Array,PE.functionReplaceTable.atan.oriStr,PE);
    },
    arccot:(Array,dt,PE)=> {
        return Derivative.checkFunctionMonomialType(Array,PE.functionReplaceTable.acot.oriStr,PE);
    },
    exp:(Array,dt,PE)=> {
        return Derivative.checkFunctionMonomialType(Array,PE.functionReplaceTable.exp.oriStr,PE);
    },
    log:(Array,dt,PE)=> {
        return Derivative.checkFunctionMonomialType(Array,PE.functionReplaceTable.log.oriStr,PE);
    }
};

/**
 * 对单项式求导
 * @private
 */
let _monoDev={
    num:(Array,dt,PE)=> {
        return ['0'];
    },
    para:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array.length===1)return ['1'];
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100) {
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr ||op.sign===PE.operatorReplaceTable.exp.oriStr){
                for(let i=0;i<array.length;i++){
                    if(array[i]===dt){
                        array[i]='1';
                    }
                }
                return array;
            }else{
                let temp=op.sign===PE.operatorReplaceTable.sub.oriStr?(()=>{
                    let ta=array.slice(op.index);
                    ta.unshift(PE.operatorReplaceTable.psl.oriStr);
                    ta.push(PE.operatorReplaceTable.psr.oriStr);
                    return ta;
                })():array.slice(op.index+1);
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        temp[i]='1';
                        return temp;
                    }
                }
                array=array.slice(0,op.index);
            }
            num++;
        }
    },
    sin:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100){
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            let temp=[];
            let spliceIndex=undefined;
            let spliceNum=0;
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr||op.sign===PE.operatorReplaceTable.exp.oriStr) {
                for (let i = 0; i < array.length-2; i++) {
                    if (array[i] === PE.functionReplaceTable.sin.oriStr) {
                        if(array[i+2]===dt){
                            if (array[i - 1] !== undefined) {
                                temp.push(array[i - 1]);
                            } else {
                                temp.push(PE.operatorReplaceTable.mul.oriStr);
                            }
                            temp.push(PE.functionReplaceTable.cos.oriStr);
                            temp.push(array[i + 1]);
                            temp.push(array[i + 2]);
                            temp.push(array[i + 3]);
                            spliceIndex = i;
                            spliceNum = 4;
                            array.splice(i, 4, '1');
                            let tempArray=[];
                            for(let j=0;j<array.length;j++) {
                                tempArray.push(array[j]);
                            }
                            for(let k=0;k<temp.length;k++){
                                if(k===0){
                                    if(tempArray.length!==0)tempArray.push(temp[k]);
                                }else {
                                    tempArray.push(temp[k]);
                                }
                            }
                            return tempArray;
                        }
                    }
                }
            }else{
                temp=array.slice(op.index+1);
                let tCount=0;
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        array=temp;
                        tCount++;
                    }
                }
                if(tCount===0)array=array.slice(0,op.index);
            }
            num++;
        }
    },
    pow:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100){
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let spliceIndex=undefined;
            let spliceNum=0;
            let isFuc=false;
            let paraPosLeft=false;
            let nPart=[];
            let fucPart=[];
            let tStr=undefined;
            let pCount=0;
            let temp=[];
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr||op.sign===PE.operatorReplaceTable.exp.oriStr){
                for(let i=0;i<array.length;i++){
                    if(array[i]===PE.functionReplaceTable.pow.oriStr){
                        fucPart=[];
                        spliceIndex=i;
                        spliceNum++;
                        fucPart.push(array[i]);
                        for(let j=i+1;j<array.length;j++){
                            fucPart.push(array[j]);
                            temp.push(array[j]);
                            spliceNum++;
                            if(array[j]===PE.operatorReplaceTable.psl.oriStr)pCount++;
                            if(array[j]===PE.operatorReplaceTable.psr.oriStr)pCount--;
                            if(array[j]===dt){
                                tStr=array[j];
                                isFuc=true;
                            }
                            if(array[j]===PE.operatorReplaceTable.cma.oriStr){
                                if(pCount===1&&isFuc===true)paraPosLeft=true;
                            }
                            if(pCount===0){
                                if(isFuc){
                                    array.splice(spliceIndex,spliceNum,'1');
                                    if(paraPosLeft){
                                        nPart=fucPart.slice(4,fucPart.length-1);
                                    }else{
                                        nPart=fucPart.slice(2,fucPart.length-3);
                                    }
                                    let n_1Part=nPart.slice(0);
                                    n_1Part.push(PE.operatorReplaceTable.sub.oriStr);
                                    n_1Part.push('1');
                                    let tempArray=[];
                                    if(!paraPosLeft) {
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        for (let k = 0; k < array.length; k++) {
                                            tempArray.push(array[k]);
                                        }
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.mul.oriStr);
                                        tempArray.push(PE.functionReplaceTable.pow.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        for (let k = 0; k < nPart.length; k++) {
                                            tempArray.push(nPart[k]);
                                        }
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.cma.oriStr);
                                        tempArray.push(tStr);
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.mul.oriStr);
                                        tempArray.push(PE.functionReplaceTable.log.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        tempArray.push(PE.constReplaceTable.e.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.cma.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        for (let k = 0; k < nPart.length; k++) {
                                            tempArray.push(nPart[k]);
                                        }
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                    }else{
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        for(let k=0;k<array.length;k++){
                                            tempArray.push(array[k]);
                                        }
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.mul.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        for(let k=0;k<nPart.length;k++){
                                            tempArray.push(nPart[k]);
                                        }
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.mul.oriStr);
                                        tempArray.push(PE.functionReplaceTable.pow.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        tempArray.push(tStr);
                                        tempArray.push(PE.operatorReplaceTable.cma.oriStr);
                                        for(let k=0;k<n_1Part.length;k++){
                                            tempArray.push(n_1Part[k]);
                                        }
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                    }
                                    return tempArray;
                                }else{
                                    fucPart=[];
                                    spliceIndex=undefined;
                                    spliceNum=0;
                                    break;
                                }
                            }
                        }
                    }
                }
            }else{
                temp=array.slice(op.index+1);
                let tCount=0;
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        array=temp;
                        tCount++;
                    }
                }
                if(tCount===0)array=array.slice(0,op.index);
            }
            num++;
        }
    },
    cos:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100){
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            let temp=[];
            let spliceIndex=undefined;
            let spliceNum=0;
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr||op.sign===PE.operatorReplaceTable.exp.oriStr) {
                for (let i = 0; i < array.length-2; i++) {
                    if (array[i] === PE.functionReplaceTable.cos.oriStr) {
                        if(array[i+2]===dt){
                            if (array[i - 1] !== undefined) {
                                temp.push(array[i - 1]);
                            } else {
                                temp.push(PE.operatorReplaceTable.mul.oriStr);
                            }
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push(PE.operatorReplaceTable.sub.oriStr);
                            temp.push(PE.functionReplaceTable.sin.oriStr);
                            temp.push(array[i + 1]);
                            temp.push(array[i + 2]);
                            temp.push(array[i + 3]);
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            spliceIndex = i;
                            spliceNum = 4;
                            array.splice(i, 4, '1');
                            let tempArray=[];
                            for(let j=0;j<array.length;j++){
                                tempArray.push(array[j]);
                            }
                            for(let k=0;k<temp.length;k++){
                                if(k===0){
                                    if(tempArray.length!==0)tempArray.push(temp[k]);
                                }else {
                                    tempArray.push(temp[k]);
                                }
                            }
                            return tempArray;
                        }
                    }
                }
            }else{
                temp=array.slice(op.index+1);
                let tCount=0;
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        array=temp;
                        tCount++;
                    }
                }
                if(tCount===0)array=array.slice(0,op.index);
            }
            num++;
        }
    },
    tan:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100){
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            let temp=[];
            let spliceIndex=undefined;
            let spliceNum=0;
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr||op.sign===PE.operatorReplaceTable.exp.oriStr) {
                for (let i = 0; i < array.length-2; i++) {
                    if (array[i] === PE.functionReplaceTable.tan.oriStr) {
                        if(array[i+2]===dt){
                            if (array[i - 1] !== undefined) {
                                temp.push(array[i - 1]);
                            } else {
                                temp.push(PE.operatorReplaceTable.mul.oriStr);
                            }
                            temp.push(PE.functionReplaceTable.pow.oriStr);
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push(PE.functionReplaceTable.sec.oriStr);
                            temp.push(array[i + 1]);
                            temp.push(array[i + 2]);
                            temp.push(array[i + 3]);
                            temp.push(PE.operatorReplaceTable.cma.oriStr);
                            temp.push('2');
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            spliceIndex = i;
                            spliceNum = 4;
                            array.splice(i, 4, '1');
                            let tempArray=[];
                            for(let j=0;j<array.length;j++){
                                tempArray.push(array[j]);
                            }
                            for(let k=0;k<temp.length;k++){
                                if(k===0){
                                    if(tempArray.length!==0)tempArray.push(temp[k]);
                                }else {
                                    tempArray.push(temp[k]);
                                }
                            }
                            return tempArray;
                        }
                    }
                }
            }else{
                temp=array.slice(op.index+1);
                let tCount=0;
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        array=temp;
                        tCount++;
                    }
                }
                if(tCount===0)array=array.slice(0,op.index);
            }
            num++;
        }
    },
    cot:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100){
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            let temp=[];
            let spliceIndex=undefined;
            let spliceNum=0;
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr||op.sign===PE.operatorReplaceTable.exp.oriStr) {
                for (let i = 0; i < array.length-2; i++) {
                    if (array[i] === PE.functionReplaceTable.cot.oriStr) {
                        if(array[i+2]===dt){
                            if (array[i - 1] !== undefined) {
                                temp.push(array[i - 1]);
                            } else {
                                temp.push(PE.operatorReplaceTable.mul.oriStr);
                            }
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push(PE.operatorReplaceTable.sub.oriStr);
                            temp.push(PE.functionReplaceTable.pow.oriStr);
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push(PE.functionReplaceTable.csc.oriStr);
                            temp.push(array[i + 1]);
                            temp.push(array[i + 2]);
                            temp.push(array[i + 3]);
                            temp.push(PE.operatorReplaceTable.cma.oriStr);
                            temp.push('2');
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            spliceIndex = i;
                            spliceNum = 4;
                            array.splice(i, 4, '1');
                            let tempArray=[];
                            for(let j=0;j<array.length;j++){
                                tempArray.push(array[j]);
                            }
                            for(let k=0;k<temp.length;k++){
                                if(k===0){
                                    if(tempArray.length!==0)tempArray.push(temp[k]);
                                }else {
                                    tempArray.push(temp[k]);
                                }
                            }
                            return tempArray;
                        }
                    }
                }
            }else{
                temp=array.slice(op.index+1);
                let tCount=0;
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        array=temp;
                        tCount++;
                    }
                }
                if(tCount===0)array=array.slice(0,op.index);
            }
            num++;
        }
    },
    sec:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100){
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            let temp=[];
            let spliceIndex=undefined;
            let spliceNum=0;
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr||op.sign===PE.operatorReplaceTable.exp.oriStr) {
                for (let i = 0; i < array.length-2; i++) {
                    if (array[i] === PE.functionReplaceTable.sec.oriStr) {
                        if(array[i+2]===dt){
                            if (array[i - 1] !== undefined) {
                                temp.push(array[i - 1]);
                            } else {
                                temp.push(PE.operatorReplaceTable.mul.oriStr);
                            }
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push(PE.functionReplaceTable.sec.oriStr);
                            temp.push(array[i + 1]);
                            temp.push(array[i + 2]);
                            temp.push(array[i + 3]);
                            temp.push(PE.operatorReplaceTable.mul.oriStr);
                            temp.push(PE.functionReplaceTable.tan.oriStr);
                            temp.push(array[i + 1]);
                            temp.push(array[i + 2]);
                            temp.push(array[i + 3]);
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            spliceIndex = i;
                            spliceNum = 4;
                            array.splice(i, 4, '1');
                            let tempArray=[];
                            for(let j=0;j<array.length;j++){
                                tempArray.push(array[j]);
                            }
                            for(let k=0;k<temp.length;k++){
                                if(k===0){
                                    if(tempArray.length!==0)tempArray.push(temp[k]);
                                }else {
                                    tempArray.push(temp[k]);
                                }
                            }
                            return tempArray;
                        }
                    }
                }
            }else{
                temp=array.slice(op.index+1);
                let tCount=0;
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        array=temp;
                        tCount++;
                    }
                }
                if(tCount===0)array=array.slice(0,op.index);
            }
            num++;
        }
    },
    csc:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100){
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            let temp=[];
            let spliceIndex=undefined;
            let spliceNum=0;
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr||op.sign===PE.operatorReplaceTable.exp.oriStr) {
                for (let i = 0; i < array.length-2; i++) {
                    if (array[i] === PE.functionReplaceTable.csc.oriStr) {
                        if(array[i+2]===dt){
                            if (array[i - 1] !== undefined) {
                                temp.push(array[i - 1]);
                            } else {
                                temp.push(PE.operatorReplaceTable.mul.oriStr);
                            }
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push(PE.operatorReplaceTable.sub.oriStr);
                            temp.push(PE.functionReplaceTable.csc.oriStr);
                            temp.push(array[i + 1]);
                            temp.push(array[i + 2]);
                            temp.push(array[i + 3]);
                            temp.push(PE.operatorReplaceTable.mul.oriStr);
                            temp.push(PE.functionReplaceTable.cot.oriStr);
                            temp.push(array[i + 1]);
                            temp.push(array[i + 2]);
                            temp.push(array[i + 3]);
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            spliceIndex = i;
                            spliceNum = 4;
                            array.splice(i, 4, '1');
                            let tempArray=[];
                            for(let j=0;j<array.length;j++){
                                tempArray.push(array[j]);
                            }
                            for(let k=0;k<temp.length;k++){
                                if(k===0){
                                    if(tempArray.length!==0)tempArray.push(temp[k]);
                                }else {
                                    tempArray.push(temp[k]);
                                }
                            }
                            return tempArray;
                        }
                    }
                }
            }else{
                temp=array.slice(op.index+1);
                let tCount=0;
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        array=temp;
                        tCount++;
                    }
                }
                if(tCount===0)array=array.slice(0,op.index);
            }
            num++;
        }
    },
    arcsin:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100){
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            let temp=[];
            let spliceIndex=undefined;
            let spliceNum=0;
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr||op.sign===PE.operatorReplaceTable.exp.oriStr) {
                for (let i = 0; i < array.length-2; i++) {
                    if (array[i] === PE.functionReplaceTable.asin.oriStr) {
                        if(array[i+2]===dt){
                            if (array[i - 1] !== undefined) {
                                temp.push(array[i - 1]);
                            } else {
                                temp.push(PE.operatorReplaceTable.mul.oriStr);
                            }
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push('1');
                            temp.push(PE.operatorReplaceTable.exp.oriStr);
                            temp.push(PE.functionReplaceTable.pow.oriStr);
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push('1');
                            temp.push(PE.operatorReplaceTable.sub.oriStr);
                            temp.push(PE.functionReplaceTable.pow.oriStr);
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push(array[i + 2]);
                            temp.push(PE.operatorReplaceTable.cma.oriStr);
                            temp.push('2');
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            temp.push(PE.operatorReplaceTable.cma.oriStr);
                            temp.push('1');
                            temp.push(PE.operatorReplaceTable.exp.oriStr);
                            temp.push('2');
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            spliceIndex = i;
                            spliceNum = 4;
                            array.splice(i, 4, '1');
                            let tempArray=[];
                            for(let j=0;j<array.length;j++){
                                tempArray.push(array[j]);
                            }
                            for(let k=0;k<temp.length;k++){
                                if(k===0){
                                    if(tempArray.length!==0)tempArray.push(temp[k]);
                                }else {
                                    tempArray.push(temp[k]);
                                }
                            }
                            return tempArray;
                        }
                    }
                }
            }else{
                temp=array.slice(op.index+1);
                let tCount=0;
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        array=temp;
                        tCount++;
                    }
                }
                if(tCount===0)array=array.slice(0,op.index);
            }
            num++;
        }
    },
    arccos:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100){
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            let temp=[];
            let spliceIndex=undefined;
            let spliceNum=0;
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr||op.sign===PE.operatorReplaceTable.exp.oriStr) {
                for (let i = 0; i < array.length-2; i++) {
                    if (array[i] === PE.functionReplaceTable.acos.oriStr) {
                        if(array[i+2]===dt){
                            if (array[i - 1] !== undefined) {
                                temp.push(array[i - 1]);
                            } else {
                                temp.push(PE.operatorReplaceTable.mul.oriStr);
                            }
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push(PE.operatorReplaceTable.sub.oriStr);
                            temp.push('1');
                            temp.push(PE.operatorReplaceTable.exp.oriStr);
                            temp.push(PE.functionReplaceTable.pow.oriStr);
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push('1');
                            temp.push(PE.operatorReplaceTable.sub.oriStr);
                            temp.push(PE.functionReplaceTable.pow.oriStr);
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push(array[i + 2]);
                            temp.push(PE.operatorReplaceTable.cma.oriStr);
                            temp.push('2');
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            temp.push(PE.operatorReplaceTable.cma.oriStr);
                            temp.push('1');
                            temp.push(PE.operatorReplaceTable.exp.oriStr);
                            temp.push('2');
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            spliceIndex = i;
                            spliceNum = 4;
                            array.splice(i, 4, '1');
                            let tempArray=[];
                            for(let j=0;j<array.length;j++){
                                tempArray.push(array[j]);
                            }
                            for(let k=0;k<temp.length;k++){
                                if(k===0){
                                    if(tempArray.length!==0)tempArray.push(temp[k]);
                                }else {
                                    tempArray.push(temp[k]);
                                }
                            }
                            return tempArray;
                        }
                    }
                }
            }else{
                temp=array.slice(op.index+1);
                let tCount=0;
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        array=temp;
                        tCount++;
                    }
                }
                if(tCount===0)array=array.slice(0,op.index);
            }
            num++;
        }
    },
    arctan:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100){
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            let temp=[];
            let spliceIndex=undefined;
            let spliceNum=0;
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr||op.sign===PE.operatorReplaceTable.exp.oriStr) {
                for (let i = 0; i < array.length-2; i++) {
                    if (array[i] === PE.functionReplaceTable.atan.oriStr) {
                        if(array[i+2]===dt){
                            if (array[i - 1] !== undefined) {
                                temp.push(array[i - 1]);
                            } else {
                                temp.push(PE.operatorReplaceTable.mul.oriStr);
                            }
                            temp.push('1');
                            temp.push(PE.operatorReplaceTable.exp.oriStr);
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push('1');
                            temp.push(PE.operatorReplaceTable.add.oriStr);
                            temp.push(PE.functionReplaceTable.pow.oriStr);
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push(array[i + 2]);
                            temp.push(PE.operatorReplaceTable.cma.oriStr);
                            temp.push('2');
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            spliceIndex = i;
                            spliceNum = 4;
                            array.splice(i, 4, '1');
                            let tempArray=[];
                            for(let j=0;j<array.length;j++){
                                tempArray.push(array[j]);
                            }
                            for(let k=0;k<temp.length;k++){
                                if(k===0){
                                    if(tempArray.length!==0)tempArray.push(temp[k]);
                                }else {
                                    tempArray.push(temp[k]);
                                }
                            }
                            return tempArray;
                        }
                    }
                }
            }else{
                temp=array.slice(op.index+1);
                let tCount=0;
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        array=temp;
                        tCount++;
                    }
                }
                if(tCount===0)array=array.slice(0,op.index);
            }
            num++;
        }
    },
    arccot:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100){
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            let temp=[];
            let spliceIndex=undefined;
            let spliceNum=0;
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr||op.sign===PE.operatorReplaceTable.exp.oriStr) {
                for (let i = 0; i < array.length-2; i++) {
                    if (array[i] === PE.functionReplaceTable.acot.oriStr) {
                        if(array[i+2]===dt){
                            if (array[i - 1] !== undefined) {
                                temp.push(array[i - 1]);
                            } else {
                                temp.push(PE.operatorReplaceTable.mul.oriStr);
                            }
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push(PE.operatorReplaceTable.sub.oriStr);
                            temp.push('1');
                            temp.push(PE.operatorReplaceTable.exp.oriStr);
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push('1');
                            temp.push(PE.operatorReplaceTable.add.oriStr);
                            temp.push(PE.functionReplaceTable.pow.oriStr);
                            temp.push(PE.operatorReplaceTable.psl.oriStr);
                            temp.push(array[i + 2]);
                            temp.push(PE.operatorReplaceTable.cma.oriStr);
                            temp.push('2');
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            temp.push(PE.operatorReplaceTable.psr.oriStr);
                            spliceIndex = i;
                            spliceNum = 4;
                            array.splice(i, 4, '1');
                            let tempArray=[];
                            for(let j=0;j<array.length;j++){
                                tempArray.push(array[j]);
                            }
                            for(let k=0;k<temp.length;k++){
                                if(k===0){
                                    if(tempArray.length!==0)tempArray.push(temp[k]);
                                }else {
                                    tempArray.push(temp[k]);
                                }
                            }
                            return tempArray;
                        }
                    }
                }
            }else{
                temp=array.slice(op.index+1);
                let tCount=0;
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        array=temp;
                        tCount++;
                    }
                }
                if(tCount===0)array=array.slice(0,op.index);
            }
            num++;
        }
    },
    exp:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100){
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            let temp=[];
            let spliceIndex=undefined;
            let spliceNum=0;
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr||op.sign===PE.operatorReplaceTable.exp.oriStr) {
                for (let i = 0; i < array.length-2; i++) {
                    if (array[i] === PE.functionReplaceTable.exp.oriStr) {
                        if(array[i+2]===dt){
                            if (array[i - 1] !== undefined) {
                                temp.push(array[i - 1]);
                            } else {
                                temp.push(PE.operatorReplaceTable.mul.oriStr);
                            }
                            temp.push(PE.functionReplaceTable.exp.oriStr);
                            temp.push(array[i + 1]);
                            temp.push(array[i + 2]);
                            temp.push(array[i + 3]);
                            spliceIndex = i;
                            spliceNum = 4;
                            array.splice(i, 4, '1');
                            let tempArray=[];
                            for(let j=0;j<array.length;j++){
                                tempArray.push(array[j]);
                            }
                            for(let k=0;k<temp.length;k++){
                                if(k===0){
                                    if(tempArray.length!==0)tempArray.push(temp[k]);
                                }else {
                                    tempArray.push(temp[k]);
                                }
                            }
                            return tempArray;
                        }
                    }
                }
            }else{
                temp=array.slice(op.index+1);
                let tCount=0;
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        array=temp;
                        tCount++;
                    }
                }
                if(tCount===0)array=array.slice(0,op.index);
            }
            num++;
        }
    },
    log:(Array,dt,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        if(array[0]===PE.operatorReplaceTable.sub.oriStr){
            array.splice(0,1);
            array.unshift(PE.operatorReplaceTable.psl.oriStr,
                PE.operatorReplaceTable.sub.oriStr,
                '1',
                PE.operatorReplaceTable.psr.oriStr,
                PE.operatorReplaceTable.mul.oriStr);
        }
        let num=0;
        while (num<100){
            if(num===99){
                console.warn("JORScripts.Derivative encountered an error!");
                return ['0'];
            }
            let spliceIndex=undefined;
            let spliceNum=0;
            let isFuc=false;
            let paraPosLeft=false;
            let nPart=[];
            let fucPart=[];
            let tStr=undefined;
            let pCount=0;
            let temp=[];
            let rootOP=Derivative.getRootOperator(array,PE);
            let op=Derivative.findLastLowestPriorityOperator(rootOP,PE);
            if(op===undefined||op.sign===PE.operatorReplaceTable.mul.oriStr||op.sign===PE.operatorReplaceTable.exp.oriStr){
                for(let i=0;i<array.length;i++){
                    if(array[i]===PE.functionReplaceTable.log.oriStr){
                        fucPart=[];
                        spliceIndex=i;
                        spliceNum++;
                        fucPart.push(array[i]);
                        for(let j=i+1;j<array.length;j++){
                            fucPart.push(array[j]);
                            temp.push(array[j]);
                            spliceNum++;
                            if(array[j]===PE.operatorReplaceTable.psl.oriStr)pCount++;
                            if(array[j]===PE.operatorReplaceTable.psr.oriStr)pCount--;
                            if(array[j]===dt){
                                tStr=array[j];
                                isFuc=true;
                            }
                            if(array[j]===PE.operatorReplaceTable.cma.oriStr){
                                if(pCount===1&&isFuc===true)paraPosLeft=true;
                            }
                            if(pCount===0){
                                if(isFuc){
                                    array.splice(spliceIndex,spliceNum,'1');
                                    if(paraPosLeft){
                                        nPart=fucPart.slice(4,fucPart.length-1);
                                    }else{
                                        nPart=fucPart.slice(2,fucPart.length-3);
                                    }
                                    let tempArray=[];
                                    if(paraPosLeft){
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.sub.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        for(let k=0;k<array.length;k++){
                                            tempArray.push(array[k]);
                                        }
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.mul.oriStr);
                                        tempArray.push(PE.functionReplaceTable.log.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        tempArray.push(tStr);
                                        tempArray.push(PE.operatorReplaceTable.cma.oriStr);
                                        for(let k=0;k<nPart.length;k++){
                                            tempArray.push(nPart[k]);
                                        }
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.exp.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        tempArray.push(tStr);
                                        tempArray.push(PE.operatorReplaceTable.mul.oriStr);
                                        tempArray.push(PE.functionReplaceTable.log.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        tempArray.push(PE.constReplaceTable.e.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.cma.oriStr);
                                        tempArray.push(tStr);
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                    }else {
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        for (let k = 0; k < array.length; k++) {
                                            tempArray.push(array[k]);
                                        }
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.exp.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        tempArray.push(tStr);
                                        tempArray.push(PE.operatorReplaceTable.mul.oriStr);
                                        tempArray.push(PE.functionReplaceTable.log.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        tempArray.push(PE.constReplaceTable.e.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.cma.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psl.oriStr);
                                        for (let k = 0; k < nPart.length; k++) {
                                            tempArray.push(nPart[k]);
                                        }
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                        tempArray.push(PE.operatorReplaceTable.psr.oriStr);
                                    }
                                    return tempArray;
                                }else{
                                    fucPart=[];
                                    spliceIndex=undefined;
                                    spliceNum=0;
                                    break;
                                }
                            }
                        }
                    }
                }
            }else{
                temp=array.slice(op.index+1);
                let tCount=0;
                for(let i=0;i<temp.length;i++){
                    if(temp[i]===dt){
                        array=temp;
                        tCount++;
                    }
                }
                if(tCount===0)array=array.slice(0,op.index);
            }
            num++;
        }
    }
};

/**
 * 对中间变量求导
 */
class devOP {
    constructor(u, v, sign, opStr, dt, PE) {
        this.u = u;
        this.v = v;
        this.sign = sign;
        this.opStr = opStr;
        this.dt = dt;
        this.PE = PE;
    }
    output() {
        switch (this.sign) {
            case this.PE.operatorReplaceTable.add.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.opStr, this.u, this.sign, this.opStr, this.v,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.operatorReplaceTable.sub.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.opStr, this.u, this.sign, this.opStr, this.v,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.operatorReplaceTable.mul.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.opStr, this.u, this.sign, this.v, this.PE.operatorReplaceTable.add.oriStr, this.u, this.sign, this.opStr, this.v,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.operatorReplaceTable.exp.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.opStr, this.u, this.PE.operatorReplaceTable.mul.oriStr,
                    this.v,
                    this.PE.operatorReplaceTable.sub.oriStr,
                    this.u, this.PE.operatorReplaceTable.mul.oriStr, this.opStr, this.v,
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.exp.oriStr,
                    this.PE.functionReplaceTable.pow.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.v,
                    this.PE.operatorReplaceTable.cma.oriStr, '2',
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.functionReplaceTable.sin.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.opStr, this.v, this.PE.operatorReplaceTable.mul.oriStr,
                    this.PE.functionReplaceTable.cos.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.v, this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.functionReplaceTable.pow.oriStr:
                let nPart = [];
                let nIndex = undefined;
                let array = this.u.slice(0);
                let pCount = 0;
                let paraLeft = false;
                for (let i = 0; i < array.length; i++) {
                    if (array[i] === this.PE.operatorReplaceTable.psl.oriStr) pCount++;
                    if (array[i] === this.PE.operatorReplaceTable.psr.oriStr) pCount--;
                    if (array[i] === this.dt) paraLeft = true;
                    if (array[i] === this.PE.operatorReplaceTable.cma.oriStr) {
                        if (pCount === 1) {
                            nIndex = i + 1;
                            break;
                        }
                    }
                }
                if (paraLeft) {
                    nPart = array.slice(nIndex, array.length - 1);
                } else {
                    nPart = array.slice(2, nIndex - 1);
                    this.v = array.slice(nIndex, array.length - 1);
                }
                let n_1Part = nPart.slice(0);
                n_1Part.push(this.PE.operatorReplaceTable.sub.oriStr);
                n_1Part.push('1');
                let elements = [];
                if (paraLeft) {
                    elements.push(this.PE.operatorReplaceTable.psl.oriStr,
                        this.opStr, this.v, this.PE.operatorReplaceTable.mul.oriStr,
                        this.PE.operatorReplaceTable.psl.oriStr);
                    elements.push(nPart);
                    elements.push(this.PE.operatorReplaceTable.psr.oriStr,
                        this.PE.operatorReplaceTable.mul.oriStr,
                        this.PE.functionReplaceTable.pow.oriStr,
                        this.PE.operatorReplaceTable.psl.oriStr,
                        this.PE.operatorReplaceTable.psl.oriStr,
                        this.v,
                        this.PE.operatorReplaceTable.psr.oriStr,
                        this.PE.operatorReplaceTable.cma.oriStr);
                    elements.push(n_1Part);
                    elements.push(this.PE.operatorReplaceTable.psr.oriStr,
                        this.PE.operatorReplaceTable.psr.oriStr);
                } else {
                    elements.push(this.PE.operatorReplaceTable.psl.oriStr);
                    elements.push(this.opStr);
                    elements.push(this.v);
                    elements.push(this.PE.operatorReplaceTable.psr.oriStr);
                    elements.push(this.PE.operatorReplaceTable.mul.oriStr);
                    elements.push(this.PE.functionReplaceTable.pow.oriStr);
                    elements.push(this.PE.operatorReplaceTable.psl.oriStr);
                    elements.push(nPart);
                    elements.push(this.PE.operatorReplaceTable.cma.oriStr);
                    elements.push(this.v);
                    elements.push(this.PE.operatorReplaceTable.psr.oriStr);
                    elements.push(this.PE.operatorReplaceTable.mul.oriStr);
                    elements.push(this.PE.functionReplaceTable.log.oriStr);
                    elements.push(this.PE.operatorReplaceTable.psl.oriStr);
                    elements.push(this.PE.constReplaceTable.e.oriStr);
                    elements.push(this.PE.operatorReplaceTable.cma.oriStr);
                    elements.push(nPart);
                    elements.push(this.PE.operatorReplaceTable.psr.oriStr);
                }
                return elements;
            case this.PE.functionReplaceTable.cos.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.opStr, this.v, this.PE.operatorReplaceTable.mul.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.PE.operatorReplaceTable.sub.oriStr,
                    this.PE.functionReplaceTable.sin.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.v, this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.functionReplaceTable.tan.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.opStr, this.v, this.PE.operatorReplaceTable.mul.oriStr,
                    this.PE.functionReplaceTable.pow.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.PE.functionReplaceTable.sec.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.v, this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.cma.oriStr, '2',
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.functionReplaceTable.cot.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.PE.operatorReplaceTable.sub.oriStr, this.opStr, this.v,
                    this.PE.operatorReplaceTable.mul.oriStr,
                    this.PE.functionReplaceTable.pow.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.PE.functionReplaceTable.csc.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr, this.v,
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.cma.oriStr, '2',
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.functionReplaceTable.sec.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.opStr, this.v, this.PE.operatorReplaceTable.mul.oriStr,
                    this.PE.functionReplaceTable.sec.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr, this.v,
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.mul.oriStr,
                    this.PE.functionReplaceTable.tan.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr, this.v,
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.functionReplaceTable.csc.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.PE.operatorReplaceTable.sub.oriStr, this.opStr, this.v,
                    this.PE.operatorReplaceTable.mul.oriStr,
                    this.PE.functionReplaceTable.csc.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.v,
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.mul.oriStr,
                    this.PE.functionReplaceTable.cot.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.v,
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.functionReplaceTable.asin.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.opStr, this.v, this.PE.operatorReplaceTable.exp.oriStr,
                    this.PE.functionReplaceTable.root.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    '2', this.PE.operatorReplaceTable.cma.oriStr,
                    '1', this.PE.operatorReplaceTable.sub.oriStr,
                    this.PE.functionReplaceTable.pow.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.v, this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.cma.oriStr,
                    '2', this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.functionReplaceTable.acos.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.PE.operatorReplaceTable.sub.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.opStr, this.v, this.PE.operatorReplaceTable.exp.oriStr,
                    this.PE.functionReplaceTable.root.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    '2', this.PE.operatorReplaceTable.cma.oriStr,
                    '1', this.PE.operatorReplaceTable.sub.oriStr,
                    this.PE.functionReplaceTable.pow.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.v, this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.cma.oriStr,
                    '2', this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.functionReplaceTable.atan.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.opStr, this.v, this.PE.operatorReplaceTable.exp.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    '1', this.PE.operatorReplaceTable.add.oriStr,
                    this.PE.functionReplaceTable.pow.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.v, this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.cma.oriStr,
                    '2',
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.functionReplaceTable.acot.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.PE.operatorReplaceTable.sub.oriStr,
                    this.opStr, this.v, this.PE.operatorReplaceTable.exp.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    '1', this.PE.operatorReplaceTable.add.oriStr,
                    this.PE.functionReplaceTable.pow.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.v, this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.cma.oriStr,
                    '2',
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.functionReplaceTable.exp.oriStr:
                return [this.PE.operatorReplaceTable.psl.oriStr,
                    this.opStr, this.v, this.PE.operatorReplaceTable.mul.oriStr,
                    this.PE.functionReplaceTable.exp.oriStr,
                    this.PE.operatorReplaceTable.psl.oriStr,
                    this.v, this.PE.operatorReplaceTable.psr.oriStr,
                    this.PE.operatorReplaceTable.psr.oriStr];
            case this.PE.functionReplaceTable.log.oriStr:
                let aPart = [];
                paraLeft = false;
                pCount = 0;
                let hasPara = false;
                for (let i = 0; i < this.u.length; i++) {
                    if (this.u[i] === this.PE.operatorReplaceTable.psl.oriStr) pCount++;
                    if (this.u[i] === this.PE.operatorReplaceTable.psr.oriStr) pCount--;
                    if (this.u[i] === this.dt) hasPara = true;
                    if (this.u[i] === this.PE.operatorReplaceTable.cma.oriStr) {
                        if (pCount === 1) {
                            if (hasPara === true) {
                                paraLeft = true;
                                break;
                            } else {
                                break;
                            }
                        }
                    }
                }
                if (paraLeft) {
                    aPart = this.u.slice(this.v.length + 3, this.u.length - 1);
                } else {
                    aPart = this.u.slice(2, this.u.length - this.v.length - 2);
                }
                elements = [];
                if (!paraLeft) {
                    elements.push(this.PE.operatorReplaceTable.psl.oriStr,
                        this.opStr, this.v, this.PE.operatorReplaceTable.exp.oriStr,
                        this.PE.operatorReplaceTable.psl.oriStr,
                        this.PE.operatorReplaceTable.psl.oriStr,
                        this.v, this.PE.operatorReplaceTable.psr.oriStr,
                        this.PE.operatorReplaceTable.mul.oriStr,
                        this.PE.functionReplaceTable.log.oriStr,
                        this.PE.operatorReplaceTable.psl.oriStr,
                        this.PE.constReplaceTable.e.oriStr,
                        this.PE.operatorReplaceTable.cma.oriStr);
                    elements.push(aPart);
                    elements.push(this.PE.operatorReplaceTable.psr.oriStr,
                        this.PE.operatorReplaceTable.psr.oriStr,
                        this.PE.operatorReplaceTable.psr.oriStr);
                } else {
                    elements.push(this.PE.operatorReplaceTable.psl.oriStr);
                    elements.push(this.PE.operatorReplaceTable.sub.oriStr);
                    elements.push(this.opStr);
                    elements.push(this.v);
                    elements.push(this.PE.operatorReplaceTable.mul.oriStr);
                    elements.push(this.PE.functionReplaceTable.log.oriStr);
                    elements.push(this.PE.operatorReplaceTable.psl.oriStr);
                    elements.push(this.v);
                    elements.push(this.PE.operatorReplaceTable.cma.oriStr);
                    elements.push(aPart);
                    elements.push(this.PE.operatorReplaceTable.psr.oriStr);
                    elements.push(this.PE.operatorReplaceTable.exp.oriStr);
                    elements.push(this.PE.operatorReplaceTable.psl.oriStr);
                    elements.push(this.v);
                    elements.push(this.PE.operatorReplaceTable.mul.oriStr);
                    elements.push(this.PE.functionReplaceTable.log.oriStr);
                    elements.push(this.PE.operatorReplaceTable.psl.oriStr);
                    elements.push(this.PE.constReplaceTable.e.oriStr);
                    elements.push(this.PE.operatorReplaceTable.cma.oriStr);
                    elements.push(this.v);
                    elements.push(this.PE.operatorReplaceTable.psr.oriStr);
                    elements.push(this.PE.operatorReplaceTable.psr.oriStr);
                    elements.push(this.PE.operatorReplaceTable.psr.oriStr);
                }
                return elements;
        }
    }
}

/**
 * 化解多项式
 */
class dev {
    constructor(array,dt,PE,uPart,vPart,opStr) {
        this.u = array;
        this.dt=dt;
        this.PE=PE;
        this.uPart=uPart;
        this.vPart=vPart;
        this.opStr=opStr;
    }
    output() {
        let monomial = Derivative.checkMonomial(this.u, this.dt, this.PE);
        if (monomial === false) {
            let rootOP = Derivative.getRootOperator(this.u,this.PE);
            let op = Derivative.findLastLowestPriorityOperator(rootOP,this.PE);
            if (op === undefined) {
                let tempArray = _simplifyResult.outer_parenthesis(this.u,this.PE);
                op = new DevOperater(tempArray[0], 0);
            }
            return Derivative.decomposeByOperator(this.u, op,this.uPart,this.vPart,this.opStr,this.dt,this.PE);
        } else {
            return Derivative.computeMonomial(this.u, monomial,this.dt,this.PE);
        }
    }
}

/**
 * 用求导规则化简原始表达式
 * @type {{m: _simplified.m, n: _simplified.n}}
 * @private
 */
let _simplified={
    n:(Array,parameters,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        for(let i=0;i<array.length;i++){
            if(Utils.ifElementInElements(array[i],parameters,false,Utils.type.str))return Array;
        }
        let temp=array.join("");
        PE.input(temp,['t']);
        return [""+PE.output([0])+""];
    },
    m:(Array,parameters,PE)=> {
        let array=_simplifyResult.outer_parenthesis(Array,PE);
        let _rootOperator=Derivative.getRootOperator(array,PE);
        let rootOP=[];
        for(let i=0;i<_rootOperator.length;i++){
            rootOP.push(_rootOperator[i].sign);
        }
        if(Utils.ifElementInElements(PE.operatorReplaceTable.add.oriStr,rootOP,false,Utils.type.str))return Array;
        if(Utils.ifElementInElements(PE.operatorReplaceTable.sub.oriStr,rootOP,false,Utils.type.str))return Array;
        let pCount=0;
        for(let i=0;i<array.length;i++){
            if(array[i]===PE.operatorReplaceTable.psl.oriStr)pCount++;
            if(array[i]===PE.operatorReplaceTable.psr.oriStr)pCount--;
            if(Utils.ifElementInElements(array[i],parameters,false,Utils.type.str)){
                if(pCount>0)return Array;
            }
        }
        let tArray=[];
        for(let i=0;i<array.length;i++){
            if(Utils.ifElementInElements(array[i],parameters,false,Utils.type.str)){
                if(array[i-1]===undefined){
                    tArray.push(PE.operatorReplaceTable.mul.oriStr);
                    tArray.push(array[i]);
                    array[i]='1';
                }else{
                    tArray.push(array[i-1]);
                    tArray.push(array[i]);
                    array[i]='1';
                }
            }
        }
        let temp=array.join("");
        PE.input(temp,['t']);
        temp=""+PE.output([0])+"";
        tArray.unshift(temp);
        return tArray;
    }
};

/**
 * 化简最终结果
 * @private
 */
let _simplifyResult= {
    add_zero:(Array,PE,parameters)=>{
        let index=Utils.findElementsPosition(Array,PE.operatorReplaceTable.add.oriStr,'0');
        if(index===-1)return Array;
        let pIndex=index+2;
        if(Array[pIndex]===undefined){
            Array.splice(index,2);
            return Array;
        }
        return Array;
    },
    outer_parenthesis:(array,PE)=>{
        let tempArray = undefined;
        let pCount = 0;
        if (array[0] !== PE.operatorReplaceTable.psl.oriStr) {
            tempArray = array.slice(0);
        } else if (array[array.length - 1] !== PE.operatorReplaceTable.psr.oriStr) {
            tempArray = array.slice(0);
        } else {
            let remove=(ary)=>{
                for (let i = 0; i < ary.length; i++) {
                    if (ary[i] === PE.operatorReplaceTable.psl.oriStr) pCount++;
                    if (ary[i] === PE.operatorReplaceTable.psr.oriStr) pCount--;
                    if (pCount === 0) {
                        if (i !== ary.length - 1) {
                            return ary.slice(0);
                        } else {
                            pCount=0;
                            let tempAry = ary.slice(1, ary.length - 1);
                            return remove(tempAry);
                        }
                    }
                }
            };
            tempArray=remove(array);
        }
        return tempArray;
    },
    zero:(Array,PE,parameters)=> {
        let array = Array.slice(0);
        for (let i = 0; i < array.length; i++) {
            if (array[i] === '0') {
                if (array[i - 1] === undefined && array[i + 1] === PE.operatorReplaceTable.add.oriStr) {
                    array.splice(i, 2);
                    array = _simplifyResult.outer_parenthesis(array,PE);
                    i--;
                    continue;
                }
                if (array[i - 1] === undefined && array[i + 1] === PE.operatorReplaceTable.sub.oriStr) {
                    array.splice(i, 1);
                    array = _simplifyResult.outer_parenthesis(array,PE);
                    i--;
                    continue;
                }
                if (array[i - 1] === undefined && array[i + 1] === PE.operatorReplaceTable.mul.oriStr) {
                    let pCount = 0;
                    for (let j = i + 1; j < array.length; j++) {
                        if (array[j] === PE.operatorReplaceTable.psl.oriStr)pCount++;
                        if (array[j] === PE.operatorReplaceTable.psr.oriStr)pCount--;
                        if (array[j] === PE.operatorReplaceTable.add.oriStr && pCount === 0) {
                            array.splice(i, j - i + 1);
                            array = _simplifyResult.outer_parenthesis(array,PE);
                            i--;
                            break;
                        } else if (array[j] === PE.operatorReplaceTable.sub.oriStr && pCount === 0) {
                            array.splice(i, j - i);
                            array = _simplifyResult.outer_parenthesis(array,PE);
                            i--;
                            break;
                        }
                    }
                    continue;
                }
                if (array[i - 1] === PE.operatorReplaceTable.psl.oriStr && array[i + 1] === PE.operatorReplaceTable.mul.oriStr) {
                    let pCount = 0;
                    for (let j = i + 1; j < array.length; j++) {
                        if (array[j] === PE.operatorReplaceTable.psl.oriStr)pCount++;
                        if (array[j] === PE.operatorReplaceTable.psr.oriStr)pCount--;
                        if (array[j] === PE.operatorReplaceTable.add.oriStr && pCount === 0) {
                            array.splice(i, j - i + 1);
                            array = _simplifyResult.outer_parenthesis(array,PE);
                            i--;
                            break;
                        } else if (array[j] === PE.operatorReplaceTable.sub.oriStr && pCount === 0) {
                            array.splice(i, j - i);
                            array = _simplifyResult.outer_parenthesis(array,PE);
                            i--;
                            break;
                        }
                    }
                    continue;
                }
                if (array[i - 1] === PE.operatorReplaceTable.psl.oriStr && array[i + 1] === PE.operatorReplaceTable.sub.oriStr) {
                    array.splice(i, 1);
                    i--;
                    continue;
                }
                if (array[i - 1] === PE.operatorReplaceTable.psl.oriStr && array[i + 1] === PE.operatorReplaceTable.add.oriStr) {
                    array.splice(i, 2);
                    i--;
                    continue;
                }
                if (array[i + 1] === PE.operatorReplaceTable.psr.oriStr) {
                    if (array[i - 1] === PE.operatorReplaceTable.add.oriStr) {
                        array.splice(i - 1, 2);
                        i--;
                        continue;
                    }
                    if (array[i - 1] === PE.operatorReplaceTable.sub.oriStr) {
                        if(array[i-2]===PE.operatorReplaceTable.psl.oriStr){
                            array.splice(i-2,4,'0');
                        }else {
                            array.splice(i - 1, 2);
                        }
                        i--;
                        continue;
                    }
                }
            }
            if (array[i] === PE.operatorReplaceTable.psl.oriStr) {
                let pCount = 0;
                for (let j = i; j < array.length; j++) {
                    if (array[j] === PE.operatorReplaceTable.psl.oriStr)pCount++;
                    if (array[j] === PE.operatorReplaceTable.psr.oriStr)pCount--;
                    if (pCount === 0) {
                        if (array[j + 1] === PE.operatorReplaceTable.mul.oriStr && array[j + 2] === '0') {
                            array.splice(i, j + 3 - i, '0');
                            i--;
                            pCount = 0;
                            break;
                        } else {
                            break;
                        }
                    }
                }
            }
        }
        return array;
    },
    negative:(Array,PE,parameters)=> {
        let array=Array.slice(0);
        for(let i=0;i<array.length;i++){
            if(array[i]===PE.operatorReplaceTable.sub.oriStr&&array[i+2]===PE.operatorReplaceTable.psr.oriStr){
                if(array[i-1]===PE.operatorReplaceTable.psl.oriStr){
                    if(array[i-2]===PE.operatorReplaceTable.psl.oriStr){
                        array.splice(i+2,1);
                        array.splice(i-1,1);
                        i--;
                        continue;
                    }
                    if(array[i-2]===PE.operatorReplaceTable.sub.oriStr){
                        if(array[i-3]===PE.operatorReplaceTable.psl.oriStr){
                            array.splice(i+2,1);
                            array.splice(i-2,3);
                            i--;
                            continue;
                        }
                    }
                }
                continue;
            }
            if(array[i]===PE.operatorReplaceTable.sub.oriStr&&array[i+1]===PE.operatorReplaceTable.psl.oriStr){
                let pCount=0;
                for(let j=i+1;j<array.length;j++){
                    if(array[j]===PE.operatorReplaceTable.psl.oriStr)pCount++;
                    if(array[j]===PE.operatorReplaceTable.psr.oriStr)pCount--;
                    if(array[j]===PE.operatorReplaceTable.add.oriStr){
                        if(pCount===1)break;
                    }
                    if(array[j]===PE.operatorReplaceTable.sub.oriStr){
                        if(pCount===1)break;
                    }
                    if(pCount===0){
                        array.splice(j,1);
                        array.splice(i+1,1);
                        i--;
                        break;
                    }
                }
            }
        }
        return array;
    },
    oneMulti:(Array,PE,parameters)=> {
        let array = Array.slice(0);
        for (let i = 0; i < array.length; i++) {
            if (array[i] === '1') {
                if (array[i - 1] === undefined && array[i + 1] === PE.operatorReplaceTable.mul.oriStr) {
                    array.splice(i, 2);
                    i--;
                }
                if (array[i - 1] !== undefined && array[i + 1] === PE.operatorReplaceTable.mul.oriStr) {
                    if (array[i - 1] === PE.operatorReplaceTable.mul.oriStr) {
                        array.splice(i, 2);
                        i--;
                    } else if (array[i - 1] === PE.operatorReplaceTable.exp.oriStr) {
                        array.splice(i - 1, 2);
                        i--;
                    } else {
                        array.splice(i, 2);
                        i--;
                    }
                }
                if (array[i - 1] !== undefined && array[i + 1] === PE.operatorReplaceTable.psr.oriStr) {
                    if (array[i - 1] === PE.operatorReplaceTable.mul.oriStr) {
                        array.splice(i - 1, 2);
                        i--;
                    }
                }
            }
        }
        return array;
    },
    parenthesis:(Array,PE,parameters)=> {
        let array = Array.slice(0);
        for (let i = 0; i < array.length; i++) {
            if (array[i - 1] === PE.operatorReplaceTable.psl.oriStr && array[i + 1] === PE.operatorReplaceTable.psr.oriStr) {
                if (!PE.isFunctionReplaceElement(array[i - 2])) {
                    array.splice(i - 1, 3, array[i]);
                    i--;
                    continue;
                }
            }
            if (array[i] === PE.operatorReplaceTable.psl.oriStr) {
                let pCount = 1;
                for (let j = i + 1; j < array.length; j++) {
                    if (array[j] === PE.operatorReplaceTable.psl.oriStr)pCount++;
                    if (array[j] === PE.operatorReplaceTable.psr.oriStr)pCount--;
                    if (pCount === 0) {
                        let temp = undefined;
                        if (j === array.length - 1) {
                            temp = array.slice(i);
                        } else {
                            temp = array.slice(i, j + 1);
                        }
                        if (Derivative.checkDuplicateParenthesis(temp,PE)) {
                            array.splice(j, 1);
                            array.splice(i, 1);
                            i--;
                            break;
                        } else {
                            break;
                        }
                    }
                }
            }
        }
        return array;
    },
    computable:(Array,PE,parameters)=> {
        let array = Array.slice(0);
        for (let i = 0; i < array.length; i++) {
            if (Utils.ifStringIsNumber(array[i])) {
                if (array[i - 1] === PE.operatorReplaceTable.cma.oriStr || array[i - 1] === PE.operatorReplaceTable.psl.oriStr) {
                    if (array[i + 1] === PE.operatorReplaceTable.psr.oriStr || array[i + 1] === PE.operatorReplaceTable.cma.oriStr)continue;
                    let pCount = 0;
                    for (let j = i + 1; j < array.length; j++) {
                        if (Utils.ifElementInElements(array[j], parameters, false, Utils.type.str))break;
                        if (array[j] === PE.operatorReplaceTable.psl.oriStr)pCount++;
                        if (array[j] === PE.operatorReplaceTable.psr.oriStr) {
                            if (pCount !== 0) {
                                pCount--;
                            } else {
                                let temp = array.slice(i, j);
                                let str = temp.join("");
                                PE.input(str, ['t']);
                                str = "" + PE.output([0]) + "";
                                array.splice(i, j - i, str);
                                i--;
                                break;
                            }
                        }
                        if (array[j] === PE.operatorReplaceTable.cma.oriStr) {
                            if (pCount === 0) {
                                let temp = array.slice(i, j);
                                let str = temp.join("");
                                PE.input(str, ['t']);
                                str = "" + PE.output([0]) + "";
                                array.splice(i, j - i, str);
                                i--;
                                break;
                            }
                        }
                    }
                }
                if (array[i + 1] === PE.operatorReplaceTable.mul.oriStr || array[i + 1] === PE.operatorReplaceTable.exp.oriStr) {
                    if (Utils.ifStringIsNumber(array[i + 2])) {
                        let temp=undefined;
                        if (i + 2 === array.length - 1) {
                            temp = array.slice(i)
                        } else {
                            temp = array.slice(i, i + 3);
                        }
                        let str = temp.join("");
                        PE.input(str, ['t']);
                        str = "" + PE.output([0]) + "";
                        array.splice(i, 3, str);
                        i--;
                    }
                }
            }
        }
        return array;
    },
    fuc:(Array,PE,parameters)=> {
        let array = Array.slice(0);
        for (let i = 0; i < array.length; i++) {
            if (array[i] === PE.functionReplaceTable.pow.oriStr) {
                let fucInfo = Derivative.getFunctionPart(array, i, _monomial.type.pow,PE);
                if (fucInfo.n === undefined)continue;
                if (fucInfo.n.length === 1 && fucInfo.n[0] === '1') {
                    array.splice(fucInfo.split, 3);
                    array.splice(fucInfo.start, 2);
                    i--;
                    continue;
                }
                if (fucInfo.n.length === 1 && fucInfo.n[0] === '0') {
                    array.splice(fucInfo.start, fucInfo.end, '1');
                    i--;
                    continue;
                }
                if (array[fucInfo.end + 1] === PE.operatorReplaceTable.cma.oriStr && array[fucInfo.start - 2] === PE.functionReplaceTable.pow.oriStr) {
                    let parentFucInfo = Derivative.getFunctionPart(array, fucInfo.start - 2, _monomial.type.pow,PE);
                    array.splice(parentFucInfo.end, 0, PE.operatorReplaceTable.psr.oriStr);
                    array.splice(parentFucInfo.split+1, 0, PE.operatorReplaceTable.psl.oriStr);
                    array.splice(parentFucInfo.split, 1, PE.operatorReplaceTable.mul.oriStr);
                    array.splice(fucInfo.split+1, 0, PE.operatorReplaceTable.psl.oriStr);
                    array.splice(parentFucInfo.start, 2);
                    i--;
                }
            }
        }
        return array;
    },
    para:(Array,PE,parameters)=> {
        let array=Array.slice(0);
        for(let i=0;i<array.length;i++){
            if(Utils.ifElementInElements(array[i],parameters,false,Utils.type.str)){
                if(array[i+1]===PE.operatorReplaceTable.mul.oriStr){
                    if(array[i+2]!==undefined&&Utils.ifStringIsNumber(array[i+2])){
                        let tempA=array[i];
                        let tempB=array[i+2];
                        array.splice(i+2,1,tempA);
                        array.splice(i,1,tempB);
                        i--;
                    }
                }
            }
        }
        return array;
    }
};

/**
 * 求导
 */
export default class Derivative {
    constructor() {
        this.eventCenter = new EventDispatcher();
        this._equation = undefined;
        this._equationArray = undefined;
        this._parameters = undefined;
        this._dt = undefined;
        this._PE = new EP.E();
        this._opStr = 'dev';
        this._uPart = undefined;
        this._vPart = undefined;
        this._errorEvent = {type: 'error', string: undefined};
    }
    //输入要求导的参数方程
    input(expression) {
        if (!expression instanceof EP.E) {
            this._errorEvent.string = 'DEV Equation input should be type of jExpression';
            this.eventCenter.dispatchEvent(this._errorEvent);
            return;
        }
        this._equation = expression;
        this._equationArray = this._equation.stringArray.slice(0);
        if (!Derivative.checkUnsupportFunction(this._equationArray, this._PE)) {
            this._errorEvent.string = "Derivative do not support piecewise function such as abs,etc...";
            this.eventCenter.dispatchEvent(this._errorEvent);
            this._equation = undefined;
            this._equationArray = undefined;
            return;
        }
        this._PE.setOprFuncCnstFrom(expression);
        this._parameters = Object.keys(this._equation.parameters).slice(0);
    }
    //根据给定的参数索引对该参数求导，输出字符串或参数方程
    outputEquation(dtIndex, returnString = true) {
        if (this._equationArray === undefined) {
            this._errorEvent.string = 'There is no Parameter Equation to Derivative,please input first!';
            this.eventCenter.dispatchEvent(this._errorEvent);
            return this._PE.input('0', this._parameters);
        }
        if (this._parameters[dtIndex] === undefined) {
            console.warn("index '" + dtIndex + "'of parameters is undefined,will Derivative with '" + this._parameters[0] + "'!");
            dtIndex = 0;
        }
        this._dt = this._parameters[dtIndex];
        let array = this._stepInA(this._equationArray);
        array = this._stepInB(array);
        array = _simplifyResult.outer_parenthesis(array, this._PE);
        array = Derivative.simplifyResult(array, this._parameters, this._PE);
        let str = array.join("");
        this._PE.input(str, this._parameters);
        return returnString ? str : this._PE;
    }
    //根据给定的参数索引对该参数求导,并输出给定的值的导数值
    outputValue(dtIndex,values) {
        if (this._equationArray === undefined) {
            console.warn('There is no Parameter Equation to Derivative,please input first!');
            return 0;
        }
        if (this._parameters[dtIndex] === undefined) {
            console.warn("index '" + dtIndex + "'of parameters is undefined,will Derivative with '" + this._parameters[0] + "'!");
            dtIndex = 0;
        }
        this._dt = this._parameters[dtIndex];
        let array = this._stepInA(this._equationArray);
        array = this._stepInB(array);
        let str = array.join("");
        this._PE.input(str, this._parameters);
        return this._PE.output(values);
    }
    //根据给定的参数索引及求导次数对该参数求高阶导数
    outputHigherDerivativeEquation(dtIndex, rank) {
        if (rank < 1) {
            console.warn("Derivative rank can not be less than 1!");
            return;
        }
        let result = undefined;
        for (let i = 0; i < rank; i++) {
            if (i === 0) {
                result = this.outputEquation(dtIndex);
            } else {
                this.input(result);
                result = this.outputEquation(dtIndex);
            }
        }
        return result;
    }
    //根据给定的参数索引及求导次数对该参数求高阶导数，根据输入值输出导数值
    outputHigherDerivativeValue(dtIndex, rank, paraValues) {
        if (rank < 1) {
            console.warn("Derivative rank can not be less than 1!");
            return;
        }
        let result = undefined;
        let DPE = this.outputHigherDerivativeEquation(dtIndex, rank);
        if (DPE === undefined) {
            console.warn("Encountered an error when output higher Derivative value,now will return 0!");
            result = 0;
        } else {
            result = DPE.output(paraValues);
        }
        return result;
    }
    //化简原始参数方程
    static simplified(Array, parameters, PE) {
        // console.log('start',Array.join(''));
        let array = Array.slice(0);
        for (let key in _simplified) {
            array = _simplified[key](array, parameters, PE);
        }
        // console.log('end',array.join(''));
        return array;
    }
    //检测给定函数的单项式类型
    static checkFunctionMonomialType(Array, fuc, PE) {
        let array = _simplifyResult.outer_parenthesis(Array, PE);
        for (let i = 0; i < array.length; i++) {
            if (array[i] === fuc)return true;
        }
        return false;
    }
    //获取当前优先级别最低的运算符
    static getRootOperator(Array, PE) {
        let array = _simplifyResult.outer_parenthesis(Array, PE);
        let _rootOperator = [];
        let parenthesisCount = 0;
        for (let i = 0; i < array.length; i++) {
            if (array[i] === PE.operatorReplaceTable.psl.oriStr) {
                parenthesisCount++;
                continue;
            }
            if (array[i] === PE.operatorReplaceTable.psr.oriStr) {
                parenthesisCount--;
                continue;
            }
            if (PE.isOperatorReplaceElement(array[i])) {
                if (parenthesisCount > 0)continue;
                _rootOperator.push(new DevOperater(array[i], i));
            }
        }
        return _rootOperator;
    }
    //查找右侧最低优先级运算符
    static findLastLowestPriorityOperator(operatorArray, PE) {
        let haveAM = false;
        let _lastLowestOperator = undefined;
        for (let i = 0; i < operatorArray.length; i++) {
            if (operatorArray[i].sign === PE.operatorReplaceTable.add.oriStr || operatorArray[i].sign === PE.operatorReplaceTable.sub.oriStr) {
                haveAM = true;
            }
            if (!haveAM) {
                _lastLowestOperator = operatorArray[i];
            } else {
                if (operatorArray[i].sign === PE.operatorReplaceTable.add.oriStr || operatorArray[i].sign === PE.operatorReplaceTable.sub.oriStr) {
                    _lastLowestOperator = operatorArray[i];
                }
            }
        }
        return _lastLowestOperator;
    }
    //检测是否含不支持的函数类型
    static checkUnsupportFunction(Array, PE) {
        for (let i = 0; i < Array.length; i++) {
            if (Array[i] === PE.functionReplaceTable.abs.oriStr)return false;
            if (Array[i] === PE.functionReplaceTable.rand.oriStr)return false;
            if (Array[i] === PE.operatorReplaceTable.mod.oriStr)return false;
            if (Array[i] === PE.functionReplaceTable.fact.oriStr)return false;
        }
        return true;
    }
    //检测重复嵌套的括号
    static checkDuplicateParenthesis(Array, PE) {
        let array = _simplifyResult.outer_parenthesis(Array, PE);
        let pCount = 0;
        if (array[0] !== PE.operatorReplaceTable.psl.oriStr) {
            return false;
        } else if (array[array.length - 1] !== PE.operatorReplaceTable.psr.oriStr) {
            return false;
        } else {
            for (let i = 0; i < array.length; i++) {
                if (array[i] === PE.operatorReplaceTable.psl.oriStr) pCount++;
                if (array[i] === PE.operatorReplaceTable.psr.oriStr) pCount--;
                if (pCount === 0) {
                    return i === array.length - 1;
                }
            }
        }
    }
    //检测单项式
    static checkMonomial(Array, dt, PE) {
        let array = _simplifyResult.outer_parenthesis(Array, PE);
        if (_monomial.para(Array, dt, PE)) {
            return _monomial.type.para;
        } else if (_monomial.num(Array, dt, PE)) {
            return _monomial.type.num;
        } else if (_monomial.oneParaFuc(Array, dt, PE)) {
            if (_monomial.sin(Array, dt, PE))return _monomial.type.sin;
            if (_monomial.cos(Array, dt, PE))return _monomial.type.cos;
            if (_monomial.tan(Array, dt, PE))return _monomial.type.tan;
            if (_monomial.cot(Array, dt, PE))return _monomial.type.cot;
            if (_monomial.sec(Array, dt, PE))return _monomial.type.sec;
            if (_monomial.csc(Array, dt, PE))return _monomial.type.csc;
            if (_monomial.arcsin(Array, dt, PE))return _monomial.type.arcsin;
            if (_monomial.arccos(Array, dt, PE))return _monomial.type.arccos;
            if (_monomial.arctan(Array, dt, PE))return _monomial.type.arctan;
            if (_monomial.arccot(Array, dt, PE))return _monomial.type.arccot;
            if (_monomial.exp(Array, dt, PE))return _monomial.type.exp;
        } else if (_monomial.twoParaFuc(Array, dt, PE)) {
            if (_monomial.pow(Array, dt, PE))return _monomial.type.pow;
            if (_monomial.log(Array, dt, PE))return _monomial.type.log;
        } else {
            return false;
        }
    }
    //计算单项式导数
    static computeMonomial(Array, type, dt, PE) {
        for (let key of Object.keys(_monomial.type)) {
            if (_monomial.type[key] === type) {
                return _monoDev[key](Array, dt, PE);
            }
        }
        return undefined;
    }
    //根据求导运算符分解复合函数
    static decomposeByOperator(Array, operator, uPart, vPart, opStr, dt, PE) {
        let array = Array.slice(0);
        if (operator === undefined)return;
        if (PE.isOperatorReplaceElement(operator.sign)) {
            uPart = array.slice(0, operator.index);
            vPart = array.slice(operator.index + 1);
            return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
        } else if (PE.isFunctionReplaceElement(operator.sign)) {
            switch (operator.sign) {
                case PE.functionReplaceTable.sin.oriStr:
                    let tArray = _simplifyResult.outer_parenthesis(array, PE);
                    uPart = tArray.slice(0);
                    tArray = tArray.slice(2, tArray.length - 1);
                    vPart = tArray.slice(0);
                    return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
                case PE.functionReplaceTable.pow.oriStr:
                    tArray = _simplifyResult.outer_parenthesis(array, PE);
                    uPart = tArray.slice(0);
                    let index = 1;
                    let pCount = 0;
                    for (let i = 2; i < tArray.length; i++) {
                        index++;
                        if (tArray[i] === PE.operatorReplaceTable.psl.oriStr) pCount++;
                        if (tArray[i] === PE.operatorReplaceTable.psr.oriStr) pCount--;
                        if (tArray[i] === PE.operatorReplaceTable.cma.oriStr) {
                            if (pCount === 0)break;
                        }
                    }
                    tArray = tArray.slice(2, index);
                    vPart = tArray.slice(0);
                    return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
                case PE.functionReplaceTable.cos.oriStr:
                    tArray = _simplifyResult.outer_parenthesis(array, PE);
                    uPart = tArray.slice(0);
                    tArray = tArray.slice(2, tArray.length - 1);
                    vPart = tArray.slice(0);
                    return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
                case PE.functionReplaceTable.tan.oriStr:
                    tArray = _simplifyResult.outer_parenthesis(array, PE);
                    uPart = tArray.slice(0);
                    tArray = tArray.slice(2, tArray.length - 1);
                    vPart = tArray.slice(0);
                    return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
                case PE.functionReplaceTable.cot.oriStr:
                    tArray = _simplifyResult.outer_parenthesis(array, PE);
                    uPart = tArray.slice(0);
                    tArray = tArray.slice(2, tArray.length - 1);
                    vPart = tArray.slice(0);
                    return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
                case PE.functionReplaceTable.sec.oriStr:
                    tArray = _simplifyResult.outer_parenthesis(array, PE);
                    uPart = tArray.slice(0);
                    tArray = tArray.slice(2, tArray.length - 1);
                    vPart = tArray.slice(0);
                    return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
                case PE.functionReplaceTable.csc.oriStr:
                    tArray = _simplifyResult.outer_parenthesis(array, PE);
                    uPart = tArray.slice(0);
                    tArray = tArray.slice(2, tArray.length - 1);
                    vPart = tArray.slice(0);
                    return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
                case PE.functionReplaceTable.asin.oriStr:
                    tArray = _simplifyResult.outer_parenthesis(array, PE);
                    uPart = tArray.slice(0);
                    tArray = tArray.slice(2, tArray.length - 1);
                    vPart = tArray.slice(0);
                    return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
                case PE.functionReplaceTable.acos.oriStr:
                    tArray = _simplifyResult.outer_parenthesis(array, PE);
                    uPart = tArray.slice(0);
                    tArray = tArray.slice(2, tArray.length - 1);
                    vPart = tArray.slice(0);
                    return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
                case PE.functionReplaceTable.atan.oriStr:
                    tArray = _simplifyResult.outer_parenthesis(array, PE);
                    uPart = tArray.slice(0);
                    tArray = tArray.slice(2, tArray.length - 1);
                    vPart = tArray.slice(0);
                    return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
                case PE.functionReplaceTable.acot.oriStr:
                    tArray = _simplifyResult.outer_parenthesis(array, PE);
                    uPart = tArray.slice(0);
                    tArray = tArray.slice(2, tArray.length - 1);
                    vPart = tArray.slice(0);
                    return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
                case PE.functionReplaceTable.exp.oriStr:
                    tArray = _simplifyResult.outer_parenthesis(array, PE);
                    uPart = tArray.slice(0);
                    tArray = tArray.slice(2, tArray.length - 1);
                    vPart = tArray.slice(0);
                    return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
                case PE.functionReplaceTable.log.oriStr:
                    tArray = _simplifyResult.outer_parenthesis(array, PE);
                    uPart = tArray.slice(0);
                    vPart = [];
                    pCount = 0;
                    let hasPara = false;
                    for (let i = 1; i < array.length; i++) {
                        vPart.push(array[i]);
                        if (array[i] === PE.operatorReplaceTable.psl.oriStr) pCount++;
                        if (array[i] === PE.operatorReplaceTable.psr.oriStr) pCount--;
                        if (array[i] === dt) hasPara = true;
                        if (array[i] === PE.operatorReplaceTable.cma.oriStr) {
                            if (pCount === 1) {
                                if (hasPara) {
                                    vPart = vPart.slice(1, vPart.length - 1);
                                    break;
                                } else {
                                    vPart = [];
                                }
                            }
                        }
                        if (pCount === 0) {
                            vPart = vPart.slice(0, vPart.length - 1);
                            break;
                        }
                    }
                    return new devOP(uPart, vPart, operator.sign, opStr, dt, PE);
            }
        } else {
            console.warn("Derivative encountered an unknown operator!");
        }
    }
    //判断是否分解彻底
    static isRoot(Array) {
        for (let i = 0; i < Array.length; i++) {
            if (typeof (Array[i]) !== 'string')return false;
        }
        return true;
    }
    //获取函数的非参数部分
    static getFunctionPart(Array, startIndex, monoType, PE) {
        let paraPart = undefined;
        let nPart = undefined;
        let pCount = 0;
        let splitIndex = undefined;
        let endIndex = undefined;
        switch (monoType) {
            case PE.functionReplaceTable.pow.oriStr:
                for (let i = startIndex + 1; i < Array.length; i++) {
                    if (Array[i] === PE.operatorReplaceTable.psl.oriStr) pCount++;
                    if (Array[i] === PE.operatorReplaceTable.psr.oriStr) {
                        pCount--;
                        if (pCount === 0) {
                            nPart = Array.slice(splitIndex + 1, i);
                            endIndex = i;
                            break;
                        }
                    }
                    if (Array[i] === PE.operatorReplaceTable.cma.oriStr) {
                        if (pCount === 1) {
                            paraPart = Array.slice(startIndex + 2, i);
                            splitIndex = i;
                        }
                    }
                }
                return {para: paraPart, n: nPart, start: startIndex, split: splitIndex, end: endIndex};
        }
    }
    //检测并将序列内子数组元素取出
    static checkAndRemoveBracket(Array) {
        let array = [];
        for (let i = 0; i < Array.length; i++) {
            if (typeof (Array[i]) === 'string') {
                array.push(Array[i]);
            } else {
                for (let j = 0; j < Array[i].length; j++) {
                    array.push(Array[i][j]);
                }
            }
        }
        return array;
    }
    //化简最终结果
    static simplifyResult(Array, parameters, PE) {
        console.log('start',Array.join(""));
        let array = Array.slice(0);
        let oriLength = 0;
        let curLength = array.length;
        while (oriLength !== curLength) {
            oriLength = array.length;
            for (let key in _simplifyResult) {
                array = _simplifyResult[key](array, PE, parameters);
                console.log('step',array.join(""));
            }
            curLength = array.length;
        }
        console.log('end',array.join(""));
        return array;
    }
    //求导第一步
    _stepInA(Array) {
        let array = _simplifyResult.outer_parenthesis(Array, this._PE);
        array = Derivative.simplified(array, this._parameters, this._PE);
        let tempDev = new dev(array, this._dt, this._PE, this._uPart, this._vPart, this._opStr);
        let result = tempDev.output();
        if (!(result instanceof devOP)) {
            return result;
        } else {
            return result.output();
        }
    }
    //求导第二步
    _stepInB(Array) {
        let array = Array.slice(0);
        let newArray = [];
        let nowDev = false;
        for (let i = 0; i < array.length; i++) {
            if (!nowDev) {
                if (array[i] !== this._opStr) {
                    newArray.push(array[i]);
                }
                if (array[i] === this._opStr) {
                    nowDev = true;
                }
            } else {
                nowDev = false;
                array[i] = this._stepInA((array[i]));
                newArray.push(array[i]);
            }
        }
        newArray = Derivative.checkAndRemoveBracket(newArray);
        if (Derivative.isRoot(newArray)) {
            return newArray;
        } else {
            return this._stepInB(newArray);
        }
    }
}